package _05_stack.my_implements.exerc;

import _05_stack.my_implements.LinkedListStack;
import org.junit.Test;

/**
 * @author: mornd
 * @dateTime: 2023/6/7 - 0:45
 * 逆波兰表达式求值，即运算符在后 (Java编译后的字节码就是按这种方式求值)
 * 运算符在后面，且不用考虑优先级，从左往右执行即可
 * 比如：
 *      [1,4,2,-,+,4,*]   结果为 (1+(4-2)) * 4  =  12
 */
public class EvalRPNTest {
    @Test
    public void test() {
        // 前提保证数组元素都是整型，且前两个必须是数字
//        String[] arr = {"4", "13", "5", "/", "+"}; // 22
//        String[] arr = {"10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"}; // 22
        String[] arr = {"1", "2", "3", "+", "*", "5", "+"}; // 10
        int r = evalRPN(arr);
        System.out.println(r);
    }

    int evalRPN(String[] arr) {
        LinkedListStack<Integer> numbers = new LinkedListStack<>();

        for (String str : arr) {
            if (isNumeric(str)) {
                numbers.push(Integer.valueOf(str));
            } else {
                if (numbers.isEmpty() || numbers.size() < 2) {
                    throw new IllegalArgumentException();
                }
                numbers.push(calc(numbers.pop(), numbers.pop(), str));
            }
        }
        if (numbers.size() != 1) {
            throw new IllegalArgumentException();
        }
        return numbers.peek();
    }

    Integer calc(Integer pop, Integer pop1, String str) {
        int r = switch (str) {
            case "+" -> {
                yield pop1 + pop;
            }
            case "-" -> pop1 - pop;
            case "*" -> pop1 * pop;
            case "/" -> pop1 / pop;
            case "%" -> pop1 % pop;
            default -> {
                throw new IllegalArgumentException();
            }
        };
        return r;
    }

    /**
     * 字符串 i 是否是整形
     *
     * @param i
     * @return
     */
    boolean isNumeric(String i) {
        try {
            Integer.parseInt(i);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

}
